
/**
 * #info
 *@author   wuwg
 *@createTime   2018/03/20
 *@updateTime    2018/05/07
 *@description  poptip  component   弹出框组件
 */

/**
 * #item
 *
 * @type        aty-poptip
 * @cn          弹出框
 * @menu        通知
 * @stPlugin    true
 * @stContainer true
 * @mixins      [./components/components/base/popper.js]
 */

/**
 * #extendproperty
 *
 * @name    slot
 * @cn      插槽
 * @type    list
 * @options [title,content]
 * @description  aty-poptip插槽，可选值为title标题，content内容
 */

import config from '../../../config/config.js'

// components
import atyButton from '../../basic/button/index.vue'
// directives
import clickoutside from '../../../directives/clickoutside.js'
import TransferDom from '../../../directives/transfer-dom.js'
// mixins
import Popper from '../../base/popper.js'
import Locale from '../../../locale/index.js'
// prefix
const prefixCls = config.prefix + '-poptip'
// module
const module = {
  name: config.prefix + '-poptip',
  mixins: [Popper, Locale],
  directives: { clickoutside, TransferDom },
  components: { atyButton },
  props: {
    /**
     * #property
     *
     * @name      trigger
     * @cn        触发方式
     * @type      list
     * @options    [click,focus,hover]
     * @value      click
     * @description   触发方式，取值为 [click,focus,hover]中的一个,在 confirm 模式下，只有 click 有效
     */
    trigger: {
      validator (value) {
        return Artery.isOneOf(value, ['click', 'focus', 'hover'])
      },
      default: 'click'
    },
    /**
     * #property
     *
     * @name    placement
     * @cn      气泡出现的位置
     * @type    list
     * @options  [ top, top-start, top-end ,
     * bottom ,bottom-start, bottom-end,
     * left , left-start , left-end ,
     * right, right-start, right-end]
     * @value    top
     * @description  气泡出现的位置，取值为
     * [ top, top-start, top-end ,
     * bottom ,bottom-start, bottom-end,
     * left , left-start , left-end ,
     * right, right-start, right-end]中的其中一个
     */
    placement: {
      validator (value) {
        return Artery.isOneOf(value, ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'])
      },
      default: 'top'
    },

    /**
     * #property
     *
     * @name      title
     * @cn        显示的标题
     * @type      string,number
     * @description   显示的标题
     */
    title: {
      type: [String, Number]
    },

    /**
     * #property
     *
     * @name      content
     * @cn        显示的正文内容
     * @type      string,number
     * @description   显示的正文内容，只在非 confirm 模式下有效
     */
    content: {
      type: [String, Number],
      default: ''
    },
    /**
     * #property
     *
     * @name      width
     * @cn        提示框的宽度
     * @type      string,number
     * @description   宽度，最小宽度为 150px，最大宽度为 250px，在 confirm 模式下，默认最大宽度为 300px
     */
    width: {
      type: [String, Number]
    },
    /**
     * #property
     *
     * @name      confirm
     * @cn        是否开启对话框模式
     * @type      boolean
     * @value     false
     * @description   是否开启对话框模式
     */
    confirm: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name      okText
     * @cn        确定按钮的文字
     * @type      string
     * @description   确定按钮的文字，只在 confirm 模式下有效
     */
    okText: {
      type: String
    },
    /**
     * #property
     *
     * @name      cancelText
     * @cn        取消按钮的文字
     * @type      string
     * @description  取消按钮的文字，只在 confirm 模式下有效
     */
    cancelText: {
      type: String
    },
    /**
     * #property
     *
     * @name      transfer
     * @cn        是否将弹层放置于 body 内
     * @type      boolean
     * @value     false
     * @description  是否将弹层放置于 body 内，
     *      在 Tabs、带有 fixed 的 Table 列内使用时，建议添加此属性，它将不受父级样式影响，从而达到更好的效果
     *
     */
    transfer: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    popperClass
     * @cn      弹出框的样式名称
     * @type    string
     * @description 弹出框的样式名称
     */
    popperClass: {
      type: String
    }
  },

  data () {
    return {
      prefixCls: prefixCls,
      showTitle: true,
      isInput: false,
      count: 0
    }
  },
  computed: {
    classes () {
      return [
                `${prefixCls}`,
                {
                  [`${prefixCls}-confirm`]: this.confirm
                }
      ]
    },
    popperClasses () {
      return [
                `${prefixCls}-popper`,
                {
                  [`${prefixCls}-confirm`]: this.transfer && this.confirm
                },
                this.popperClass
      ]
    },
    styles () {
      const style = {}

      if (this.width) {
        style.width = `${this.width}px`
      }
      return style
    },
    localeOkText () {
      if (this.okText === undefined) {
        return this.t('i.poptip.okText')
      } else {
        return this.okText
      }
    },
    localeCancelText () {
      if (this.cancelText === undefined) {
        return this.t('i.poptip.cancelText')
      } else {
        return this.cancelText
      }
    }
  },
  methods: {
    handleClick (event) {
      event.stopPropagation()
      if (this.confirm) {
        this.visible = !this.visible
        return true
      }
      if (this.trigger !== 'click') {
        return false
      }
      this.visible = !this.visible
    },
    handleClose () {
      if (this.confirm) {
        this.visible = false
        return true
      }
      if (this.trigger !== 'click') {
        return false
      }
      this.visible = false
    },
    handleFocus (fromInput = true) {
      if (this.trigger !== 'focus' || this.confirm || (this.isInput && !fromInput)) {
        return false
      }
      this.visible = true
    },
    handleBlur (fromInput = true) {
      if (this.trigger !== 'focus' || this.confirm || (this.isInput && !fromInput)) {
        return false
      }
      this.visible = false
    },
    handleMouseenter () {
      if (this.trigger !== 'hover' || this.confirm || !(this.$slots.title || this.title) && !(this.$slots.content || this.content)) {
        return false
      }
      if (this.enterTimer) clearTimeout(this.enterTimer)
      this.enterTimer = setTimeout(() => {
        this.visible = true
      }, 100)
    },
    handleMouseleave () {
      if (this.trigger !== 'hover' || !(this.$slots.title || this.title) && !(this.$slots.content || this.content)) {
        return false
      }
      if (this.enterTimer) {
        clearTimeout(this.enterTimer)
        this.enterTimer = setTimeout(() => {
          this.visible = false
        }, 100)
      }
    },
    // 取消
    cancel () {
      this.visible = false
      /**
       * #event
       *
       * @name    cancel
       * @body
       * @description   弹出框点击取消按钮时触发
       */
      this.$emit('cancel')
    },
    // 确定
    ok () {
      this.visible = false
      /**
       * #event
       *
       * @name    ok
       * @body
       * @description   弹出框点击确定按钮时触发
       */
      this.$emit('ok')
    },
    getInputChildren () {
      const $input = this.$refs.reference.querySelectorAll('input')
      const $textarea = this.$refs.reference.querySelectorAll('textarea')
      let $children = null

      if ($input.length) {
        $children = $input[0]
      } else if ($textarea.length) {
        $children = $textarea[0]
      }

      return $children
    }
  },
  updated () {

  },
  created () {

  },
  mounted () {
    if (!this.confirm) {
      //            this.showTitle = this.$refs.title.innerHTML != `<div class="${prefixCls}-title-inner"></div>`;
      this.showTitle = (this.$slots.title !== undefined) || this.title
    }
    // if trigger and children is input or textarea,listen focus & blur event
    if (this.trigger === 'focus') {
      this.$nextTick(() => {
        const $children = this.getInputChildren()
        if ($children) {
          this.isInput = true
          $children.addEventListener('focus', this.handleFocus, false)
          $children.addEventListener('blur', this.handleBlur, false)
        }
      })
    }
  },
  beforeDestroy () {
    const $children = this.getInputChildren()
    if ($children) {
      $children.removeEventListener('focus', this.handleFocus, false)
      $children.removeEventListener('blur', this.handleBlur, false)
    }
  }
}
export default module
